• It is a DirectX11 based rendering software showcasing a dynamic terrain influenced by Perlin noise height maps, custom multiple textures, and dynamic tessellation.
• It is integrated with a realistic day-night cycle and volumetric clouds, with basic collision detection and gameplay mechanics.
• I have implemented the entirety of the project, using DirectX11 pipeline, C++, and HLSL, alongside RenderDoc utility to debug and verify stages of the render.
• This project is used in the Graphics and Procedural Programming modules of my MSc, and also serves as a learning project for the DirectX11 pipeline and RenderDoc.
• Implemented Perlin noise derived terrain, alongside dynamic tessellation and precise surface normal calculations.
• Created a volumetric cloud system adhering to fluid mechanics. The clouds further use 3D-Perlin noise for realistic formation, movement, and environment interaction.
• Devised a flexible terrain shading system, allowing for three different materials based on height map and user provided values. Also created a sky dome and a day-night cycle with a sun affecting scene lighting and color grading.
• Programmed gameplay and collision detection using height map values, allowing for accurate object placement and interaction.
• Implemented a post-processing stack, including color grading and multi-pass bloom effects for enhanced visual fidelity.
• Designed and implemented a comprehensive UI (using ImGui) for real-time control over the entire simulation parameters, some of them are, time of day, terrain features, and cloud dynamics.
// The Ray Marching Loop
for (int i = 0; i < sA_SamNo_G.y; i++)
{
float t = t0 + stepSize * (i + randVal);
float3 samplePoint = rayOrigin + t * rayDir;
// Perlin noise density
float3 uvw = (samplePoint - boxMin) / (boxMax - boxMin);
uvw += float3(scrollSpeed.x * time, 0, scrollSpeed.y * time);
float perlinVal = texture0.SampleLevel(Sampler0, uvw, 0).r;
float rho = density * (perlinVal * 0.5 + 0.5);
// Beer's law
float scattCoeff = (sA_SamNo_G.x + sigma_s) * rho;
float sampleTransparency = exp(-stepSize * scattCoeff);
transparency *= sampleTransparency;
if (transparency < 0.001) { transparency = 0.001f; break; }
// Lighting & scattering
float light_t0, light_t1;
if (intersectAABB(samplePoint, lightDir, boxMin, boxMax, light_t0, light_t1))
{
float cos_theta = dot(normalize(lightDir), normalize(-rayDir));
float lightFalloff = exp(-light_t1 * scattCoeff);
result += transparency *
HGPhaseFunc(sA_SamNo_G.z, cos_theta) *
float4(max(saturate(lightColor.rgb * 15), 0.01), 1) *
lightFalloff * sigma_s * stepSize;
}
}
// Final blend with background
finalColor.rgb = (backgroundColor.rgb * transparency) + result.rgb;
// Gamma correction
finalColor.rgb = pow(finalColor.rgb, 1 / 2.2);
// returning with final attenuation, it'd be useful in blending with other render texture
return float4(finalColor.rgb, transparency);
Shader File (GitHub)